﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Net.Mail;
using System.Net;

namespace SerialReportService
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("SerialReportSource1"))
            {
                System.Diagnostics.EventLog.CreateEventSource(
                    "SerialReportSource1", "SerialReport");
            }
            eventLog1.Source = "SerialReportSource1";
            eventLog1.Log = "SerialReport";
        }

        protected override void OnStart(string[] args)
        {
            eventLog1.WriteEntry("In OnStart");

            try
            {
                serialPort1.PortName = Properties.Settings.Default.comPortName;
            }
            catch (Exception ex)
            {
                this.eventLog1.WriteEntry("Failed setting com port: " + ex.StackTrace + " Message:  " + ex.Message);
            }
            this.eventLog1.WriteEntry("Got com port");
            if (!this.serialPort1.IsOpen)
            {
                try
                {
                    this.serialPort1.Open();
                }
                catch (Exception ex)
                {
                    this.eventLog1.WriteEntry("Failed opening com port: " + ex.StackTrace + " Message:  " + ex.Message);
                }
            }
            else
            {
                this.eventLog1.WriteEntry("Serial port is already opened.");
            }
        }

        protected override void OnStop()
        {
            this.eventLog1.WriteEntry("Attempting message...");
            SendMessage("Serial Report Service stopping", 'R');
            this.serialPort1.Close();
            eventLog1.WriteEntry("In OnStop.");
        }



        private void SendMessage(string strMessage, char chrQualifier)
        {
            this.eventLog1.WriteEntry("Formulating message...");
            string text = "";
            string mailServer = Properties.Settings.Default.mailServer;
            string mailTo = Properties.Settings.Default.mailTo;
            string mailFrom = Properties.Settings.Default.mailFrom;
            string subject = "New Alarm Message";
            switch (chrQualifier)
            {
                case 'E':
                    text = "New event or opening: ";
                    break;
                case 'R':
                    text = "New restore or closing: ";
                    break;
                case 'e':
                    text = "New event or opening: ";
                    break;
                case 'r':
                    text = "New restore or closing: ";
                    break;
            }

            string body = string.Concat(new string[]
			{
				text,
				strMessage,
				". Police#: ",
				Properties.Settings.Default.phonePolice,
				" Fire#: ",
				Properties.Settings.Default.phoneFire
			});
            this.eventLog1.WriteEntry("Sending to: " + Properties.Settings.Default.mailTo + "We have: " + body);
            MailMessage mailMessage = new MailMessage(mailFrom, mailTo, subject, body);
            try
            {
                
                SmtpClient smtpClient = new SmtpClient(mailServer);
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = new NetworkCredential(Properties.Settings.Default.mailUserName,
                    Properties.Settings.Default.mailPassword);
                smtpClient.Port = Convert.ToInt16(Properties.Settings.Default.mailSMTPPort);
                smtpClient.Host = mailServer;
                smtpClient.EnableSsl = Convert.ToBoolean(Properties.Settings.Default.mailUseSSL);
                smtpClient.Send(mailMessage);
            }
            catch (FormatException ex)
            {
                this.eventLog1.WriteEntry(ex.StackTrace + " Message  " + ex.Message);
            }
            catch (SmtpException ex)
            {
                this.eventLog1.WriteEntry(ex.StackTrace + " Message  " + ex.Message);
            }
            catch (Exception ex)
            {
                this.eventLog1.WriteEntry(ex.StackTrace + " Message  " + ex.Message);
            }
            finally
            {
                mailMessage.Dispose();
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            ReceivedText(this.serialPort1.ReadTo("\u0014"));
        }

        private void ReceivedText(string text)
        {
            byte[] buffer = new byte[]
			{
				6
			};
            this.serialPort1.Write(buffer, 0, 1);
            int intProtocolNumber = Convert.ToInt16(text.Substring(0, 1));
            int intReceiverNumber = Convert.ToInt16(text.Substring(1, 2));
            int intLineNumber = Convert.ToInt16(text.Substring(3, 1));
            string strContactIDFormatIdentifier = text.Substring(5, 2);
            string strAccountCode = text.Substring(7, 4);
            char chrQualifier = Convert.ToChar(text.Substring(11, 1));
            string strClassCode = text.Substring(12, 3);
            string strGroupNumber = text.Substring(15, 2);
            string strZoneCode = text.Substring(17, 2);
            if (intProtocolNumber != 1)
            {
                this.eventLog1.WriteEntry("Sur-Gard message: " + text + "\r" +
                    "Protocol Number = " + Convert.ToString(intProtocolNumber) + "\r" +
                    "Receiver Number = " + Convert.ToString(intReceiverNumber) + "\r" +
                    "Line Number = " + Convert.ToString(intLineNumber) + "\r" +
                    "Contact ID Format Identifier = " + strContactIDFormatIdentifier + "\r" +
                    "Account Code = " + strAccountCode + "\r" +
                    "Qualifier = " + Convert.ToString(chrQualifier) + "\r" +
                    "Class Code = " + strClassCode + "\r" +
                    "Group Number = " + strGroupNumber + "\r" +
                    "Zone Code = " + strZoneCode + "\r");
            }
            switch (strClassCode)
            {
                case "100":
                    this.SendMessage("Auxiliary", chrQualifier);
                    break;
                case "110":
                    this.SendMessage("Fire, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "121":
                    this.SendMessage("Ambush", chrQualifier);
                    break;
                case "122":
                    this.SendMessage("Hold-Up", chrQualifier);
                    break;
                case "123":
                    this.SendMessage("Panic", chrQualifier);
                    break;
                case "130":
                    this.SendMessage("Burglary, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "137":
                    this.SendMessage("Keypad Tamper", chrQualifier);
                    break;
                case "140":
                    this.SendMessage("Keypad Auxiliary", chrQualifier);
                    break;
                case "145":
                    this.SendMessage("EZM Tamper, Module: " + strZoneCode, chrQualifier);
                    break;
                case "150":
                    this.SendMessage("24hr Aux.", chrQualifier);
                    break;
                case "151":
                    this.SendMessage("Gas Alarm", chrQualifier);
                    break;
                case "158":
                    this.SendMessage("Heat Alarm", chrQualifier);
                    break;
                case "301":
                    this.SendMessage("AC Failure", chrQualifier);
                    break;
                case "302":
                    this.SendMessage("Low System Battery", chrQualifier);
                    break;
                case "303":
                    this.SendMessage("Memory Failure", chrQualifier);
                    break;
                case "321":
                    this.SendMessage("Bell Supervision", chrQualifier);
                    break;
                case "333":
                    this.SendMessage("RF Receiver Failure", chrQualifier);
                    break;
                case "351":
                    this.SendMessage("Telco Fail Restore", chrQualifier);
                    break;
                case "370":
                    this.SendMessage("Day Zone Trouble, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "373":
                    this.SendMessage("Fire Trouble, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "381":
                    this.SendMessage("Wireless Trouble, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "384":
                    this.SendMessage("Wireless Low Battery, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "400":
                    this.SendMessage("Conditional Close/Open After Alarm/Force Close, User: " + strZoneCode, chrQualifier);
                    break;
                case "401":
                    this.SendMessage("Auto Arm/Remote Arm & Disarm/Easy Arm/Keyswitch Arm & Disarm, Zone:" + strZoneCode, chrQualifier);
                    break;
                case "404":
                    this.SendMessage("Fail to Open/Fail to Close", chrQualifier);
                    break;
                case "406":
                    this.SendMessage("Alarm Cancel", chrQualifier);
                    break;
                case "570":
                    this.SendMessage("Select Bypass in Conditional Close/Status Report, Zone: " + strZoneCode, chrQualifier);
                    break;
                case "602":
                    this.SendMessage("Test Timer", chrQualifier);
                    break;
                case "999":
                    this.SendMessage("Keyfob Low Battery", chrQualifier);
                    break;
            }
            text = "";
        }
    }
}
